package com.shuang.graph2;
//
//import java.util.*;
////方法一：深搜dfs
//public class Main{
//    //定义全局变量用来计算当前位置的上下左右四个方向
//    static int[][] dir = new int[][]{{0,1},{1,0},{-1,0},{0,-1}};
//
//    public static void main(String[] args){
//        Scanner sc = new Scanner(System.in);
//
//        //输入n m 矩阵的行和列
//        int n = sc.nextInt();
//        int m = sc.nextInt();
//
//        //存储的矩阵
//        int[][] graph = new int[n][m];
//
//        //输入矩阵信息
//        for (int i = 0; i < n; i++){
//            for (int j = 0; j < m; j++){
//                graph[i][j] = sc.nextInt();
//            }
//        }
//
//        //定义二维数组作为标记数组 用来标记是否遍历过矩阵中的陆地位置
//        boolean[][] visited = new boolean[n][m];
//
//        //用于记录结果的
//        int result = 0;
//
//        //遍历矩阵中的各个位置
//        for (int i = 0; i < n; i++){
//            for (int j = 0; j < m; j++){
//                if (graph[i][j] == 1 && !visited[i][j]){
//                    //如果遇到矩阵中的陆地并且还是没有遍历过的
//                    //先将此位置标记访问过
//                    visited[i][j] = true;
//                    //遇到陆地肯定要有一个岛屿 只不过要寻找其上下左右是否有与其相连的陆地即可
//                    result++;
//
//                    //深搜dfs寻找相连的陆地
//                    dfs(graph, visited, i, j);
//                }
//            }
//        }
//
//        System.out.print(result);
//    }
//
//    private static void dfs(int[][] graph, boolean[][] visited, int x, int y){
//
//        //寻找当前坐标位置四个方向的x和y坐标
//        for (int i = 0; i < 4; i++){
//            int nextX = x + dir[i][0];
//            int nextY = y + dir[i][1];
//
//            //越界判断处理
//            if (nextX < 0 || nextX >= graph.length || nextY < 0 || nextY >= graph[0].length){
//                continue; //坐标越界了找下一个方向
//            }
//
//            //终止条件也在这其中了 最后一定会把所有访问过的陆地都标记上 就不会无限递归下去
//            if (graph[nextX][nextY] == 1 && !visited[nextX][nextY]){
//                //如果当前位置的四个方向中有陆地 并且还没有被访问过则说明陆地相连成岛屿
//                //将访问过陆地的标记
//                visited[nextX][nextY] = true;
//
//                //递归找下一个位置的相连情况
//                dfs(graph, visited, nextX, nextY);
//            }
//        }
//
//    }
//}


import java.util.*;
//方法二：广搜bfs
public class Main {
    //定义全局变量用来计算当前位置的上下左右四个方向 (按照上右下左的逆时针方向)
    static int[][] dir = new int[][] {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        //输入n m 矩阵的行和列
        int n = sc.nextInt();
        int m = sc.nextInt();

        //存储的矩阵
        int[][] graph = new int[n][m];

        //输入矩阵信息
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                graph[i][j] = sc.nextInt();
            }
        }

        //定义二维数组作为标记数组 用来标记是否遍历过矩阵中的陆地位置
        boolean[][] visited = new boolean[n][m];

        //用于记录结果的
        int result = 0;

        //遍历矩阵中的各个位置
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (graph[i][j] == 1 && !visited[i][j]) {
                    //如果遇到矩阵中的陆地并且还是没有遍历过的
                    //先将此位置标记访问过
                    visited[i][j] = true;
                    //遇到陆地肯定要有一个岛屿 只不过要寻找其上下左右是否有与其相连的陆地即可
                    result++;

                    //bfs寻找相连的陆地
                    bfs(graph, visited, i, j);
                }
            }
        }

        System.out.print(result);
    }

    private static class pair {
        Integer first;

        Integer second;

        pair(int x, int y){
            first = x;
            second = y;
        }
    }

    private static void bfs(int[][] graph, boolean[][] visited, int x, int y) {

        //定义坐标队列，没有现成的pair类，在上面自定义了
        Queue<pair> queue = new LinkedList<>();

        //将x y坐标作为一组值加入队列中
        queue.add(new pair(x, y));
        //加入队列的时候就要把其坐标位置标记变成访问过的
        // 否则出队时才标记的话会导致重复访问，比如下方节点会在右下顺序的时候被第二次访问入队
        visited[x][y] = true;

        while (!queue.isEmpty()) {
            //队列不为空的时候要一直找

            //将队列中先进去的坐标取出来 找其四周方向与其相连的陆地
            int curX = queue.peek().first;
            int curY = queue.poll().second;

            //寻找当前坐标位置四周方向的x和y坐标
            for (int i = 0; i < 4; i++) {
                int nextX = curX + dir[i][0];
                int nextY = curY + dir[i][1];

                //越界判断处理
                if (nextX < 0 || nextX >= graph.length || nextY < 0 || nextY >= graph[0].length) {
                    continue; //坐标越界了找下一个方向
                }

                if (graph[nextX][nextY] == 1 && !visited[nextX][nextY]) {
                    //如果当前位置的四个方向中有陆地 并且还没有被访问过则说明陆地相连成岛屿
                    //将满足的加入到队列中为了后续下一轮寻找
                    queue.add(new pair(nextX, nextY));
                    //将访问过陆地的标记
                    visited[nextX][nextY] = true;
                }
            }
        }
    }
}